'''
Created on 28/03/2014

@author: jpfuertes
'''


# flat: bemol b
# sharp:  sostenido #

class Note(object):
    
    notes = [('C',),
             ('C#','Db'),
             ('D',),
             ('D#','Eb'),
             ('E',),
             ('F',),
             ('F#','Gb'),
             ('G',),
             ('G#','Ab'),
             ('A',),
             ('A#','Bb'),
             ('B',)]


        
    
    
    def __init__(self,char,level):
        self.__char = char                        
        self.__level = level
        
    def get_char(self):
        return self.__char
    
    def get_level(self):
        return self.__level
    
    char = property(get_char)
        
    level = property(get_level)

    def __repr__(self):
        return '%s (%s)' % (self.__char,self.__level)

    def __str__(self):
        return '%s (%s)' % (self.__char,self.__level) 
    
    def __cmp__(self,other):
        assert(isinstance(other,Note))            
        
        my_idx = self.__get_note_idx(self.char)
        other_idx = self.__get_note_idx(other.char)
        return cmp((my_idx,self.level),(other_idx,other.level))
        
        
    def __get_note_idx(self,c):
        for x in self.notes:
            if c in x:
                idx = self.notes.index(x)
        return idx
    
    def similar_note(self,note):
        if self.char == note.char:
            return self.level - note.level
        else:
            return None
    
    def prev(self):
        idx = self.__get_note_idx(self.char)
        level = self.level        
                # last note, start again
        if idx == 0:
            notes = self.notes[-1]     
            level -= 1  # Restart from previous level.       
        else:
            notes = self.notes[idx - 1]
                        
        new_note_char = notes[1] if len(notes) > 1 else notes[0]
        return Note(new_note_char,level)
    
    def next(self):
        idx = self.__get_note_idx(self.char)
        level = self.level        
                # last note, start again
        if idx + 1 == len(self.notes):
            notes = self.notes[0]
            level += 1 # Restart from next level. 
        else:
            notes = self.notes[idx + 1]
                                            
        return Note(notes[0],level)
    
class C(Note):            
    def __init__(self,level):
        super(C,self).__init__('C',level)
    
class D(Note):
    def __init__(self,level):
        super(D,self).__init__('D',level)

class E(Note):
    def __init__(self,level):
        super(E,self).__init__('E',level)

class F(Note):
    def __init__(self,level):
        super(F,self).__init__('F',level)

class G(Note):
    def __init__(self,level):
        super(G,self).__init__('G',level)

class A(Note):
    
    def __init__(self,level):
        super(A,self).__init__('A',level)

class B(Note):
    
    def __init__(self,level):
        super(B,self).__init__('B',level)

